﻿//
// eCRAM, a monthly activity report web application
// Copyright (C) 2010  Aptea
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using eCRAM.Model;
using eCRAM.Tools;
using Microsoft.Practices.ObjectBuilder2;

namespace eCRAM.Dao
{
    /// <summary>
    /// Contains the list of all users available in the eCRAM application.
    /// </summary>
    /// 
    /// <remarks>
    /// An administrator can give eCRAM access to employes and subcontractors.
    /// A CRAM user has a username, a password, an id and can be active or inactive.
    /// A CRAM user also has a first name, familly name, its company name...
    /// 
    /// A CRAM user can define week ends, holidays, RTTs... inside its CRAM.
    /// He can also define its occupancy, values can be 0, 1/2, 1. This is the time
    /// that took the task during the day
    /// (0 = no work, 1/2 = half day work, 1 = full day work).
    /// </remarks>
    public static class UserRepository
    {
        /// <summary>
        /// Get all users
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<User> GetAll()
        {
            using (var context = new eCramDataContext())
            {
                var loadOptions = new DataLoadOptions();
                loadOptions.LoadWith<User>(u => u.User_Activities);
                loadOptions.LoadWith<User_Activity>(u => u.Activity);
                context.LoadOptions = loadOptions;
                return context.Users.ToList();
            }
        }

        /// <summary>
        /// Insert user
        /// </summary>
        /// <param name="user"></param>
        public static void Create(User user)
        {
            using (var context = new eCramDataContext())
            {
                user.Id = Guid.NewGuid();
                user.CreationDate = DateTime.Now;
                context.Users.InsertOnSubmit(user);
                context.SubmitChanges();
            }
        }



        /// <summary>
        /// Delete user
        /// </summary>
        /// <param name="user"></param>
        public static void Delete(User user)
        {
            using (var context = new eCramDataContext())
            {
                context.Users.Attach(user);
                context.Users.DeleteOnSubmit(user);
                context.SubmitChanges();
            }
        }

        /// <summary>
        /// Get user by id
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static User GetById(Guid userId)
        {
            using (var context = new eCramDataContext())
            {
                var dlo = new DataLoadOptions();
                dlo.LoadWith<User>(u => u.User_Activities);
                dlo.LoadWith<User_Activity>( u => u.Activity);
                context.LoadOptions = dlo;

                return context.Users.Where(p => p.Id == userId).Single();
            }
        }

        /// <summary>
        /// Get only user list from start to limit 
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static IEnumerable<User> GetTop(int start, int end)
        {
            using (var context = new eCramDataContext())
            {
                return context.Users
                    .Skip(start)
                    .Take(end - start)
                    .ToList();
            }
        }

        /// <summary>
        /// Get the Users Count in db
        /// </summary>
        /// <returns></returns>
        public static int GetCount()
        {
            using (var context = new eCramDataContext())
            {
                return context.Users.Count();
            }
        }

        /// <summary>
        /// Tell us if username is available to be createde or not (username must be unique)
        /// </summary>
        /// <param name="login"></param>
        /// <param name="userId">if userId is not Empty, we just check if username already exist 
        /// in db for an other user, if not check if user name exist in db</param>
        /// <returns></returns>
        public static bool UserNameIsAvailable(string login, Guid userId)
        {
            using (var context = new eCramDataContext())
            {
                if (userId == Guid.Empty)
                {
                    return context.Users.Any(u => u.Login == login);
                }
                return context.Users.Any(u => (u.Login == login) && (u.Id != userId));
            }
        }

        /// <summary>
        /// Récupére un utilisateur à partir de son login
        /// </summary>
        /// <param name="login"></param>
        /// <returns></returns>
        public static User GetUserByLogin(string login)
        {
            using (var context = new eCramDataContext())
            {
                return context.Users.Where( u => u.Login == login).FirstOrDefault();
            }
        }

        public static void Update(User user)
        {
            using (var context = new eCramDataContext())
            {
                LinqTools.Update(user, u=> u.Id == user.Id, context);
                context.SubmitChanges();
            }
        }

        public static void DeleteUserActivity(Guid idUserActivity)
        {
            using (var context = new eCramDataContext())
            {
                context.User_Activities.Where(u => u.Id == idUserActivity).ForEach(u => context.User_Activities.DeleteOnSubmit(u));
                context.SubmitChanges();
            }
        }

        public static void AddUserActivity(User_Activity item)
        {
            using (var context = new eCramDataContext())
            {
                context.User_Activities.InsertOnSubmit(item);
                context.SubmitChanges();
            }
        }
    }
}
